#include "HttpServer.hpp"
#include "logMessage.hpp"
#include "Util.hpp"

#include <iostream>
#include <string>
#include <vector>
#include <memory>


using namespace std;
const static uint16_t port = 8888;
const static string webRoot = "./wwwroot";
const static string defaulthomepage = "index.html";
const static string page404 = "./wwwroot/err404.html";
const static string SEP = "\r\n";

class HttpRequest
{
public:
    HttpRequest() : _path(webRoot)
    {}

    ~HttpRequest(){}

    string _method;
    string _url;
    string _httpversion;
    
    vector<string> _body;

    string _path;
    string _suffix;
};

HttpRequest Deserialize(string& message)
{
    HttpRequest req;
    string line = Util::ReadOneLine(message,SEP);
    Util::ParseRequestLine(line,&req._method,&req._url,&req._httpversion);

    while(!message.empty())
    {
        line  = Util::ReadOneLine(message,SEP);
        req._body.push_back(line);
    }

    //完整的路径
    req._path += req._url;
    if(req._path[req._path.size()-1] == '/')
    {
        //检查是否用 / 请求资源
        req._path += defaulthomepage;
    }

    int pos = req._path.rfind(".");
    if(pos == std::string::npos) req._suffix = ".html";
    else req._suffix = req._path.substr(pos);

    return req;

}


string GetContentType(const string &suffix)
{
    string content_type = "Content-Type: ";

    if (suffix == ".html" || suffix == ".htm")
        content_type += "text/html";
    else if (suffix == ".css")
        content_type += "text/css";
    else if (suffix == ".js")
        content_type += "application/x-javascript";
    else if (suffix == ".png")
        content_type += "image/png";
    else if (suffix == ".jpg")
        content_type += "image/jpeg";
    else
    {
    }

    return content_type + SEP;
}

string func(string &request)
{
    cout << request << endl;


    //2 反序列化和分析请求
    HttpRequest req = Deserialize(request);

    logMessage(Debug,"请求的路径 %s",req._path.c_str());

    //3 使用请求,文件内容都读到body里
    string body;
    bool ret = Util::ReadFile(req._path,&body);


    //response
    string response;
    if(ret)
    {
        response += "HTTP/1.0 200 OK" + SEP;
        response += "Content-Length: " + to_string(body.size()) + SEP;
        response += GetContentType(req._suffix);
        response += SEP;

        response += body;
    }
    else
    {
        
        response += "HTTP/1.0 404 Not Found" + SEP;
        Util::ReadFile(page404,&body);
        response += "Content-Length: " + to_string(body.size()) + SEP;
        response += GetContentType(req._suffix);

        response += SEP;
        
        response += body;

    }

    //4 测试重定向
    // std::string response;
    // response += "HTTP/1.0 302 Found" + SEP;
    // response += "Location: https://www.qq.com/" + SEP;
    // response += SEP;

    return response;
}

int main(int argc, char *argv[])
{

    unique_ptr<ns_HttpServer::HttpServer> phtps(new ns_HttpServer::HttpServer(func, port));

    phtps->InitServer();
    phtps->StartServer();

    return 0;
}
